<?php
namespace app\common\utils;

class Http
{
    /**
     * 默认配置
     * @var array
     */
    private static $defaultOptions = [
        'timeout' => 30,
        'verify_ssl' => false,
        'return_type' => 'array', // array|string
        'cert_file' => '',
        'cert_key_file' => '',
        'cert_password' => ''
    ];

    /**
     * 发送GET请求
     * @param string $url 请求URL
     * @param array $params 请求参数
     * @param array $headers 请求头
     * @param array $options 配置项
     * @return array|string
     */
    public static function get($url, $params = [], $headers = [], $options = [])
    {
        return self::request('GET', $url, $params, $headers, $options);
    }

    /**
     * 发送POST请求
     * @param string $url 请求URL
     * @param array $data 请求数据
     * @param array $headers 请求头
     * @param array $options 配置项
     * @return array|string
     */
    public static function post($url, $data = [], $headers = [], $options = [])
    {
        return self::request('POST', $url, $data, $headers, $options);
    }
    public static function CURL($url, $data = [], $method = 'GET', $header = [])
    {
        $ch = curl_init();

        if ($method === 'GET') {
            if ($data) {
                $querystring = http_build_query($data);
                $url = $url . '?' . $querystring;
            }
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        if ($header) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }

        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);

        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        } else if ($method !== 'GET') {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }

        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }

    /**
     * 发送PUT请求
     * @param string $url 请求URL
     * @param array $data 请求数据
     * @param array $headers 请求头
     * @param array $options 配置项
     * @return array|string
     */
    public static function put($url, $data = [], $headers = [], $options = [])
    {
        return self::request('PUT', $url, $data, $headers, $options);
    }

    /**
     * 发送DELETE请求
     * @param string $url 请求URL
     * @param array $data 请求数据
     * @param array $headers 请求头
     * @param array $options 配置项
     * @return array|string
     */
    public static function delete($url, $data = [], $headers = [], $options = [])
    {
        return self::request('DELETE', $url, $data, $headers, $options);
    }

    /**
     * 发送请求
     * @param string $method 请求方法
     * @param string $url 请求URL
     * @param array $data 请求数据
     * @param array $headers 请求头
     * @param array $options 配置项
     * @return array|string
     * @throws \Exception
     */
    private static function request($method, $url, $data = [], $headers = [], $options = [])
    {
        $options = array_merge(self::$defaultOptions, $options);

        // 处理GET请求参数
        if ($method == 'GET' && !empty($data)) {
            $url .= (strpos($url, '?') === false ? '?' : '&') . http_build_query($data);
        }

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, $options['timeout']);
        curl_setopt($ch, CURLOPT_HEADER, false);

        // SSL证书验证
        if ($options['verify_ssl']) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        } else {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        // 设置证书
        if (!empty($options['cert_file'])) {
            curl_setopt($ch, CURLOPT_SSLCERT, $options['cert_file']);
            if (!empty($options['cert_key_file'])) {
                curl_setopt($ch, CURLOPT_SSLKEY, $options['cert_key_file']);
            }
            if (!empty($options['cert_password'])) {
                curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $options['cert_password']);
            }
        }

        // 设置请求方法和数据
        switch ($method) {
            case 'POST':
                curl_setopt($ch, CURLOPT_POST, true);
                break;
            case 'PUT':
            case 'DELETE':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
                break;
        }

        // 非GET请求时设置请求数据
        if ($method != 'GET' && !empty($data)) {
            $dataString = is_array($data) ? json_encode($data) : $data;
            curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
            // 设置默认Content-Type
            $headers = array_merge(['Content-Type: application/json'], $headers);
        }

        // 设置请求头
        if (!empty($headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }

        $response = curl_exec($ch);
        $error = curl_error($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($error) {
            throw new \Exception('请求发生错误: ' . $error);
        }

        // 处理响应结果
        if ($options['return_type'] == 'array') {
            $result = json_decode($response, true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new \Exception('响应解析失败: ' . json_last_error_msg());
            }
            return $result;
        }

        return $response;
    }
}